home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
ada
/
gwuada_9.zip
/
6.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-07-27
|
38KB
|
1,256 lines
/*
* Copyright (C) 1985-1992 New York University
*
* This file is part of the Ada/Ed-C system. See the Ada/Ed README file for
* warranty (none) and distribution info and also the GNU General Public
* License for more details.
*/
#include "hdr.h"
#include "libhdr.h"
#include "vars.h"
#include "setp.h"
#include "dclmapp.h"
#include "errmsgp.h"
#include "miscp.h"
#include "smiscp.h"
#include "nodesp.h"
#include "utilp.h"
#include "chapp.h"
#include "libp.h"
static void invisible_designator(Node, char *);
static Tuple derived_formals(Symbol, Tuple);
static void proc_or_entry(Node);
static void new_over_spec(Symbol, int, Symbol, Tuple, Symbol, Node);
void subprog_decl(Node node) /*;subprog_decl*/
{
Node spec_node, id_node, neq_node, eq_node;
Symbol subp_name, neq;
int exists;
Forset fs1;
if (cdebug2 > 3) TO_ERRFILE("AT PROC : subprog_decl");
spec_node = N_AST1(node);
id_node = N_AST1(spec_node);
new_compunit("ss", id_node);
adasem(spec_node);
check_spec(node);
subp_name = N_UNQ(id_node);
save_subprog_info(subp_name);
/* Modify the node kind for subprogram declarations to be
* as_subprogram_decl_tr so that their specification part need not be
* saved in the tree automatically. The formal part will be saved by
* collect_unit_nodes only in the case of a subprogram specification
* that is not in the same unit as the body as it is then needed for
* conformance checks. In addition the node as_procedure (as_function)
* is no longer needed in the tree since this info is obtained from
* the symbol table.
* Since the spec part is now dropped we now move the id_node info
* (name of the subprogram) to the N_UNQ filed of the as_subprogram_decl_tr
* node directly.
*/
N_KIND(node) = as_subprogram_decl_tr;
N_UNQ(node) = N_UNQ(id_node);
if (streq(N_VAL(id_node) , "=") && tup_size(SIGNATURE(subp_name)) == 2) {
/* build tree for declaration of inequality that was just introduced
* (in the current scope, or the enclosing one, if now in private part).
*/
exists = FALSE;
FORSET(neq = (Symbol), OVERLOADS(dcl_get(DECLARED(SCOPE_OF(subp_name)),
"/=")), fs1);
if ( same_signature(neq, subp_name) ) {
exists = TRUE;
break;
}
ENDFORSET(fs1);
if (exists) {
neq_node = copy_tree(node); /* a valid subprogram decl*/
N_UNQ(neq_node) = neq;
eq_node = copy_node(node);
make_insert_node(node, tup_new1((char *) eq_node), neq_node);
}
}
}
void check_spec(Node node) /*;check_spec*/
{
/* If the subprogram name is an operator designator, verify that it has
* the proper type and number of arguments.
*/
int proc_nat;
Node spec_node, id_node, formal_node, ret_node;
char *proc_id;
Tuple formals;
Symbol ret;
Symbol prog_name;
int spec_kind, node_kind;
if (cdebug2 > 3) TO_ERRFILE("AT PROC : check_spec ");
spec_node = N_AST1(node);
id_node = N_AST1(spec_node);
formal_node = N_AST2(spec_node);
ret_node = N_AST3(spec_node);
proc_id = N_VAL(id_node);
spec_kind = N_KIND(spec_node);
if (spec_kind == as_procedure)
ret = symbol_none;
else
ret = N_UNQ(ret_node);
switch (node_kind = N_KIND(node)) {
case as_subprogram_decl:
if (spec_kind == as_procedure)
proc_nat = na_procedure_spec;
else
proc_nat = na_function_spec;
break;
case as_subprogram:
case as_subprogram_stub:
case as_generic_subp:
if (spec_kind == as_procedure)
proc_nat = na_procedure;
else
proc_nat = na_function;
break;
}
formals = get_formals(formal_node, proc_id);
check_out_parameters(formals);
if (in_op_designators(proc_id ))
check_new_op(id_node, formals, ret);
prog_name = chain_overloads(proc_id, proc_nat, ret, formals, (Symbol)0,
formal_node);
N_UNQ(id_node) = prog_name;
}
void check_new_op(Node id_node, Tuple formals, Symbol ret) /*;check_new_op */
{
/* apply special checks for definition of operators */
char *proc_id;
Tuple tup;
Fortup ft1;
Node initv;
int exists;
Symbol typ1;
proc_id = N_VAL(id_node);
if ((strcmp(proc_id , "+") == 0 || strcmp(proc_id, "-") == 0)
&& tup_size(formals) == 1)
; /* Unary operators.*/
else if ( (strcmp(proc_id , "not") == 0 || strcmp(proc_id, "abs") == 0)
? tup_size(formals) == 1 : tup_size(formals) == 2 )
;
else {
errmsg_str("Incorrect no. of arguments for operator %" , proc_id,
"6.7", id_node);
}
exists = FALSE;
FORTUP(tup = (Tuple), formals, ft1);
initv = (Node)tup[4];
if (initv != OPT_NODE) {
exists = TRUE;
break;
}
ENDFORTUP(ft1);
if (exists) {
errmsg("Initializations not allowed for operators", "6.7", initv);
}
/* Apply the special checks on redefinitions of equality.*/
else if (streq(proc_id , "=")) {
typ1 = (Symbol) ((Tuple)formals[1])[3]; /* type of formal*/
if (tup_size(formals) != 2
|| typ1 != (Symbol) ((Tuple)formals[2])[3]
|| ret != symbol_boolean) {
errmsg("Invalid argument profile for \"=\"", "6.7", id_node);
}
}
else if (strcmp(proc_id , "/=") == 0) {
errmsg(" /= cannot be given an explicit definition", "6.7", id_node);
}
} /* end check_new_op */
Tuple get_formals(Node formal_list, char *proc_id) /*;get_formals*/
{
/* Utility to format the formals of a subprogram specification, in the
* internal form kept in the subprogram's signature.
*/
Node formal_node, id_list, m_node, type_node, exp_node, id_node;
Tuple formals, tup;
Fortup ft1, ft2;
int formal_index, f_mode;
Symbol type_mark;
formal_index = 0;
FORTUP(formal_node = (Node), N_LIST(formal_list), ft1);
id_list = N_AST1(formal_node);
FORTUP(id_node = (Node), N_LIST(id_list), ft2);
formal_index++;
ENDFORTUP(ft2);
ENDFORTUP(ft1);
formals = tup_new(formal_index);
formal_index = 0;
FORTUP(formal_node = (Node), N_LIST(formal_list), ft1);
id_list = N_AST1(formal_node);
m_node = N_AST2(formal_node);
type_node = N_AST3(formal_node);
invisible_designator(type_node, proc_id);
exp_node = N_AST4(formal_node);
invisible_designator(exp_node, proc_id);
f_mode = (int) N_VAL(m_node);
if (f_mode == 0) f_mode = na_in; /* note using 0 for '' f_mode case */
type_mark = find_type(copy_tree(type_node)); /* for conformance check */
FORTUP(id_node = (Node), N_LIST(id_list), ft2);
formal_index++;
tup = tup_new(4);
tup[1] = (char *)N_VAL(id_node);
tup[2] = (char *) f_mode;
tup[3] = (char *) type_mark;
tup[4] = (char *) copy_tree(exp_node);
formals[formal_index] = (char *) tup;
ENDFORTUP(ft2);
ENDFORTUP(ft1);
return (formals);
}
static void invisible_designator(Node tree_node, char *proc_id)
/*;invisible_designator*/
{
/*
* check for premature use of formals
*/
int nk;
Node n;
Fortup ft1;
/* The designator of a subprogram is not visible within its specification.*/
nk = N_KIND(tree_node);
if (N_KIND(tree_node) == as_simple_name) {
if (streq(N_VAL(tree_node), proc_id))
errmsg_str("premature usage of %", proc_id, "8.3(16)", tree_node);
}
else {
if (N_AST1_DEFINED(nk)) invisible_designator(N_AST1(tree_node),proc_id);
if (N_AST2_DEFINED(nk)) invisible_designator(N_AST2(tree_node),proc_id);
if (N_AST3_DEFINED(nk)) invisible_designator(N_AST3(tree_node),proc_id);
if (N_AST4_DEFINED(nk)) invisible_designator(N_AST4(tree_node),proc_id);
if (N_LIST_DEFINED(nk) && N_LIST(tree_node) != (Tuple)0) {
FORTUP(n = (Node), N_LIST(tree_node), ft1);
invisible_designator(n, proc_id);
ENDFORTUP(ft1);
}
}
}
void subprog_body(Node node) /*;subprog_body*/
{
Node specs_node, id_node, stats_node;
Node eq_node, neq_node;
char *spec_name, *prog_id;
Symbol unname, prog_name, neq, scope;
int i;
Forset fs1;
Fortup ft1;
int exists;
Tuple decscopes, decmaps, s_info;
/* s_info may not be needed ds 30 jul*/
Unitdecl ud;
if (cdebug2 > 3) TO_ERRFILE("AT PROC : subprog_body");
specs_node = N_AST1(node);
id_node = N_AST1(specs_node);
adasem(id_node);
prog_id = N_VAL(id_node);
if (IS_COMP_UNIT) {
new_compunit("su", id_node);
/* If the specification of the unit was itself a compilation unit, we
* will verify that the two specs are conforming. If this is the
* body to a generic comp. unit, will have to access and update the
* spec. In both c